﻿using Colorful.Furniture.CommonManagement;
using Colorful.Furniture.ErpSupplierManagement;
using Colorful.Furniture.Extensions;
using Colorful.Furniture.PermissionManagement;
using Colorful.Furniture.SysManagement;
using Colorful.Furniture.Wrappers;
using FreeSql;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Colorful.Furniture.ErpCustomerManagement;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Users;
using Volo.Abp.Validation;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.UnionPromoterProductListResponse.Types.Product.Types.Coupon.Types.CouponDetail.Types;
using System.Security.AccessControl;
using Volo.Abp.Auditing;
using Essensoft.Paylink.Alipay.Domain;
using Volo.Abp.ObjectMapping;
using Colorful.Furniture.CommonDto;

namespace Colorful.Furniture.ErpInventoryManagement;


/// <summary>
///  产品管理
/// </summary>
[Authorize]
public class InventoryAppService : ApplicationService
{
    private readonly IBaseRepository<Inventory> _inventoryRepository;
    private readonly IBaseRepository<SysDictionary> _sysDictionaryRepository;
    private readonly IFreeSql _freeSql;
    private readonly ILogger<InventoryAppService> _logger;
    private readonly IBaseRepository<Supplier> _supplierRepository;
    private readonly FileAppService _fileAppService;
    private readonly IBaseRepository<InventoryLog> _inventoryLogRepository;
    private readonly IDatabase _redisCache;
    private readonly IBaseRepository<InventoryProduct> _inventorySkuRepository;
    private readonly IBaseRepository<InventoryWithCustomer> _inventoryWithCustomerRepository;
    private readonly ICurrentUser _currentUser;
    private readonly IBaseRepository<SysManager> _sysManagerRepository;
    private readonly IObjectMapper _objectMapper;

    public InventoryAppService(
        IBaseRepository<Inventory> inventoryRepository,
        IBaseRepository<SysDictionary> sysDictionaryRepository,
        IFreeSql freeSql,
        ILogger<InventoryAppService> logger,
        IBaseRepository<Supplier> supplierRepository,
        FileAppService fileAppService,
        IConnectionMultiplexer connectionMultiplexer,
        IBaseRepository<InventoryLog> inventoryLogRepository,
        IBaseRepository<InventoryProduct> inventorySkuRepository,
        IBaseRepository<InventoryWithCustomer> inventoryWithCustomerRepository,
        ICurrentUser currentUser,
        IBaseRepository<SysManager> sysManagerRepository,
        IObjectMapper objectMapper
    )
    {
        _inventoryRepository = inventoryRepository;
        _sysDictionaryRepository = sysDictionaryRepository;
        _freeSql = freeSql;
        _logger = logger;
        _supplierRepository = supplierRepository;
        _fileAppService = fileAppService;
        _inventoryLogRepository = inventoryLogRepository;
        _inventorySkuRepository = inventorySkuRepository;
        _redisCache = connectionMultiplexer.GetDatabase();
        _inventoryWithCustomerRepository = inventoryWithCustomerRepository;
        _currentUser = currentUser;
        _sysManagerRepository = sysManagerRepository;
        _objectMapper = objectMapper;
    }

    /// <summary>
    ///  产品分页
    /// </summary>
    /// <returns></returns>
    [DisableAuditing]
    public async Task<PageResponseWrapper<List<InventoryPagedOutputDto>>> PostPagedAsync(
        [FromBody] InventoryPagedInputDto input)
    {

        var list = await _freeSql.Select<Inventory, SysManager>()
            .LeftJoin(x => x.t1.AddUserId == x.t2.Id)
            .WhereIf(input.ProductType.HasValue, x => x.t1.ProductType == input.ProductType)
            .WhereIf(!string.IsNullOrWhiteSpace(input.Product), x => x.t1.ProductNo.Contains(input.Product.Trim()) 
                                                                     || x.t1.ProductName.Contains(input.Product.Trim()) || x.t1.SupplierProductCode.Contains(input.Product.Trim()))
            .WhereIf(!string.IsNullOrWhiteSpace(input.SupplierName), x => x.t1.SupplierName.Contains(input.SupplierName) 
                                                                     || x.t1.SupplierProductCode.Contains(input.Product.Trim()) )
            .WhereIf(input.CategoryId.HasValue, x => x.t1.CategoryId == input.CategoryId)
            .Page(input.PageIndex, input.PageSize)
            .OrderByDescending(x => x.t1.Status)
            .OrderByDescending(x => x.t1.Sort)
            .OrderByDescending(x => x.t1.AddTime) //按照创建时间倒序
            .Count(out var pageTotalCount)
            .ToListAsync(x => new InventoryPagedOutputDto
            {
                Id = x.t1.Id,
                AddUserName = x.t2.Name
            });

        var inventoryIdList = list.Select(x => x.Id);

        var supplierList = _freeSql
            .Select<InventoryProduct, Supplier>()
            .LeftJoin(y => y.t1.SupplierId == y.t2.Id)
            .Where(y => inventoryIdList.Contains(y.t1.InventoryId) && y.t1.IsEnable == 1)
            .OrderByDescending(x => x.t1.Sort)
            .OrderBy(x => x.t1.AddTime)
            .ToList(y => new RawInventorySupplierOutputDto
            {
                SupplierName = y.t2.Name,
                CostPrice = y.t1.CostPrice,
                SupplierQty = y.t1.SupplierQty,
                MaxQty = y.t1.MaxQty,
                AcctType = y.t1.AcctType,
            });

        list.ForEach(x =>
        {
            x.SupplierOutputList = supplierList.Where(y => y.InventoryId == x.Id).ToList();
        });

        var customerList = _freeSql
            .Select<InventoryWithCustomer, Customer>()
            .LeftJoin(y => y.t1.CustomerId == y.t2.Id)
            .Where(y => inventoryIdList.Contains(y.t1.InventoryId))
            .OrderBy(x => x.t1.AddTime)
            .ToList(y => new RawInventoryCustomerOutputDto
            {
                CustomerName = y.t2.Name,
                Discount = y.t1.Discount,
                SalePrice = y.t1.SalePrice,
                InventoryId = y.t1.InventoryId
            });

        list.ForEach(x =>
        {
            x.CustomerOutputList = customerList.Where(y => y.InventoryId == x.Id).ToList();
        });


        var page = new PageResponseWrapper<List<InventoryPagedOutputDto>>
        {
            Total = pageTotalCount,
            Items = list
        };

        return page;
    }


    /// <summary>
    ///  客户产品分页
    /// </summary>
    /// <returns></returns>
    [DisableAuditing]
    public async Task<PageResponseWrapper<List<CustomerInventoryPagedOutputDto>>> PostCustomerPagedAsync(
        [FromBody] InventoryPagedInputDto input)
    {

        var list = await _freeSql.Select<Inventory, SysManager, InventoryWithCustomer, Customer>()
            .LeftJoin(x => x.t1.AddUserId == x.t2.Id)
            .LeftJoin(x => x.t1.Id == x.t3.InventoryId)
            .LeftJoin(x => x.t3.CustomerId == x.t4.Id)
            .WhereIf(input.ProductType.HasValue, x => x.t1.ProductType == input.ProductType)
            .WhereIf(!string.IsNullOrWhiteSpace(input.Product), x => x.t1.ProductNo.Contains(input.Product) || x.t1.ProductName.Contains(input.Product))
            .WhereIf(!string.IsNullOrWhiteSpace(input.SupplierName), x => x.t1.SupplierName.Contains(input.SupplierName))
            .WhereIf(!string.IsNullOrWhiteSpace(input.CustomerName), x => x.t4.Name.Contains(input.CustomerName))
            .WhereIf(input.CategoryId.HasValue, x => x.t1.CategoryId == input.CategoryId)
            .WhereIf(input.IsTest != null, x => x.t1.IsTest == input.IsTest)
            .Where(x => x.t1.Status == 3 && x.t1.IsTest == 0)
            .Page(input.PageIndex, input.PageSize)
            .OrderByDescending(x => x.t1.Sort)
            .OrderByDescending(x => x.t4.AddTime)
            .OrderByDescending(x => x.t1.AddTime) //按照创建时间倒序
            .Count(out var pageTotalCount)
            .ToListAsync(x => new CustomerInventoryPagedOutputDto
            {
                Id = x.t1.Id,
                AddUserName = x.t2.Name,
                CustomerName = x.t4.Name,
                Discount = x.t3.Discount,
                SalePrice = x.t3.SalePrice,

            });

        var page = new PageResponseWrapper<List<CustomerInventoryPagedOutputDto>>
        {
            Total = pageTotalCount,
            Items = list
        };

        return page;
    }

    /// <summary>
    ///  产品客户分页
    /// </summary>
    /// <returns></returns>
    [DisableAuditing]
    public async Task<PageResponseWrapper<List<CustomerInventoryPagedOutputDto>>> PostInventoryCustomerPagedAsync([FromBody] InventoryPagedInputDto input)
    {

        var list = await _freeSql.Select<Inventory, SysManager, InventoryWithCustomer, Customer>()
            .LeftJoin(x => x.t1.AddUserId == x.t2.Id)
            .LeftJoin(x => x.t1.Id == x.t3.InventoryId)
            .LeftJoin(x => x.t3.CustomerId == x.t4.Id)
            .WhereIf(input.ProductType.HasValue, x => x.t1.ProductType == input.ProductType)
            .WhereIf(!string.IsNullOrWhiteSpace(input.Product), x => x.t1.ProductNo.Contains(input.Product) || x.t1.ProductName.Contains(input.Product))
            .WhereIf(!string.IsNullOrWhiteSpace(input.SupplierName), x => x.t1.SupplierName.Contains(input.SupplierName))
            .WhereIf(!string.IsNullOrWhiteSpace(input.CustomerName), x => x.t4.Name.Contains(input.CustomerName))
            .WhereIf(input.CategoryId.HasValue, x => x.t1.CategoryId == input.CategoryId)
            .WhereIf(input.IsTest != null, x => x.t1.IsTest == input.IsTest)
            .Where(x => x.t1.Status == 3 && x.t1.IsTest == 0)
            .Page(input.PageIndex, input.PageSize)
            .OrderByDescending(x => x.t1.Sort)
            .OrderByDescending(x => x.t1.AddTime) //按照创建时间倒序
            .Count(out var pageTotalCount)
            .ToListAsync(x => new CustomerInventoryPagedOutputDto
            {
                Id = x.t1.Id,
                AddUserName = x.t2.Name,
                CustomerName = x.t4.Name,
                Discount = x.t3.Discount,
                SalePrice = x.t3.SalePrice,
                CustomerCode = x.t4.Code.ToString()

            });

        var page = new PageResponseWrapper<List<CustomerInventoryPagedOutputDto>>
        {
            Total = pageTotalCount,
            Items = list
        };

        return page;
    }

    /// <summary>
    ///  产品供应商分页
    /// </summary>
    /// <returns></returns>
    [DisableAuditing]
    public async Task<PageResponseWrapper<List<InventorySupplierPagedOutputDto>>> PostInventorySupplierPagedAsync([FromBody] InventoryPagedInputDto input)
    {

        var list = await _freeSql.Select<Inventory, InventoryProduct, Supplier>()
            .LeftJoin(x => x.t1.Id == x.t2.InventoryId)
            .LeftJoin(x => x.t2.SupplierId == x.t3.Id)
            .WhereIf(input.ProductType.HasValue, x => x.t1.ProductType == input.ProductType)
            .WhereIf(!string.IsNullOrWhiteSpace(input.Product), x => x.t1.ProductNo.Contains(input.Product) || x.t1.ProductName.Contains(input.Product))
            .WhereIf(!string.IsNullOrWhiteSpace(input.SupplierName), x => x.t1.SupplierName.Contains(input.SupplierName))
            .WhereIf(input.CategoryId.HasValue, x => x.t1.CategoryId == input.CategoryId)
            .WhereIf(input.IsTest != null, x => x.t1.IsTest == input.IsTest)
            .Where(x => x.t1.Status == 3 && x.t2.IsEnable == 1 && x.t1.IsTest == 0)
            .Page(input.PageIndex, input.PageSize)
            .OrderByDescending(x => x.t1.Sort)
            .OrderByDescending(x => x.t1.AddTime) //按照创建时间倒序
            .Count(out var pageTotalCount)
            .ToListAsync(x => new InventorySupplierPagedOutputDto
            {
                Id = x.t1.Id,
                SupplierName = x.t3.Name,
                CostPrice = x.t2.CostPrice,
                SupplierQty = x.t2.SupplierQty,
                MaxQty = x.t2.MaxQty,
                AddTime = x.t2.AddTime
            });

        var page = new PageResponseWrapper<List<InventorySupplierPagedOutputDto>>
        {
            Total = pageTotalCount,
            Items = list
        };

        return page;
    }

    /// <summary>
    ///  日志
    /// </summary>
    /// <returns></returns>
    public async Task<List<InventoryLogPagedOutputDto>> GetLogListAsync(Guid inventoryId)
    {
        var list = await _inventoryLogRepository
            .Where(x => x.InventoryId == inventoryId)
            .OrderByDescending(x => x.AddTime) //按照创建时间倒序
            .ToListAsync(x => new InventoryLogPagedOutputDto());

        return list;
    }


    /// <summary>
    ///  获取图片从标准文件对象中
    /// </summary>
    /// <param name="fileInputList"></param>
    /// <returns></returns>
    private string GetUrlFirst(List<FileStandardDto> fileInputList)
    {
        if (fileInputList == null || !fileInputList.Any())
            return null;

        return fileInputList.First().Url;
    }


    /// <summary>
    /// 保存商品配置
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<Guid?> SaveDetailAsync(InventoryDetailSaveInputDto input)
    {
        input.BackgroundImg = GetUrlFirst(input.BackgroundImgList);
        input.SecondPopImg = GetUrlFirst(input.SecondPopImgList);
        //input.CoverImg = GetUrlFirst(input.CoverImgList);
        //input.Content = GetUrlFirst(input.ContentList);
        //修改
        if (!input.Id.IsNull())
        {
            var info = await _freeSql.Select<Inventory>()
                .Where(x => x.Id == input.Id).ToOneAsync();

            var model = _objectMapper.Map(input, info);

            await _freeSql.Update<Inventory>()
                .SetSource(model)
                .ExecuteAffrowsAsync();

            return input.Id;
        }

        return new Guid();
    }


    /// <summary>
    ///  保存产品
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    /// <exception cref="AbpValidationException">验证异常</exception>
    /// <exception cref="UserFriendlyException">友好异常</exception>
    public async Task<bool> SaveRawAsync(InventoryRawSaveInputDto input)
    {
        var validResultList = new List<ValidationResult>();
        // 请选择产品产品类型
        if (!input.CategoryId.HasValue)
            validResultList.Add(new ValidationResult("请选择产品类型"));

        //根据选择的产品分类获取产品类型
        var parentCategoryCode = await _sysDictionaryRepository.Where(x => x.Id == input.CategoryId)
            .Include(x => x.Parent)
            .ToOneAsync(x => x.Parent.Code);

        if (parentCategoryCode == null)
            validResultList.Add(new ValidationResult("请选择正确的类别"));

        if (validResultList.Any())
            throw new AbpValidationException(validResultList);

        //如果产品编号为空
        if (string.IsNullOrWhiteSpace(input.ProductNo))
        {
            input.ProductNo = GetProductNo(input.CategoryId);
        }

        ////判断是否产品名称是否唯一
        //var isExistProductName = await _inventoryRepository
        //    .Where(x => x.ProductName == input.ProductName && x.Id != input.Id)
        //    .AnyAsync();

        //if (isExistProductName)
        //    throw new UserFriendlyException($"产品名称[{input.ProductName}]已存在，请更换");

        ////判断是否产品编号是否唯一
        //var productNoInfo = await _inventoryRepository
        //    .Where(x => x.ProductNo == input.ProductNo && x.Id != input.Id)
        //    .ToOneAsync(x => new { x.ProductNo, x.ProductName });

        //if (productNoInfo != null)
        //    throw new UserFriendlyException($"产品[{productNoInfo.ProductName}]编号{input.ProductNo}已存在，请更换");

        //获得供应商信息
        var supplierName = "";
        var supplierProductCode = "";
        var num = 1;
        foreach (var item in input.InventorySkus.Where(x => x.IsEnable == 1).OrderByDescending(x => x.Sort))
        {
            supplierName += await _supplierRepository.Where(x => x.Id == item.SupplierId).ToOneAsync(x => x.Name);
            //supplierName += " ( " + item.SupplierProductName + " [ " + item.SupplierProductNo + " ] )";
            supplierName += " ( " + item.CostPrice + "  )";
            if (num < input.InventorySkus.Count())
            {
                supplierName += " ， ";
            }

            supplierProductCode += $"{item.SupplierProductNo},";

            num++;
        }

        input.SupplierName = supplierName;
        input.SupplierProductCode = supplierProductCode;

        if (!input.Id.HasValue)
        {
            var inventory = ObjectMapper.Map<InventoryRawSaveInputDto, Inventory>(input);

            //新增时，给定默认值
            inventory.Status = 2;

            await _inventoryRepository.InsertAsync(inventory);

            if (input.InventorySkus.Any())
            {
                inventory.InventorySkus = input.InventorySkus.Select(x =>
                {
                    var inventorySku = ObjectMapper.Map<InventorySkuInputDto, InventoryProduct>(x);

                    inventorySku.ProductNo = inventory.ProductNo;

                    return inventorySku;
                }).ToList();

                await _inventoryRepository.SaveManyAsync(inventory, nameof(inventory.InventorySkus));
            }
        }
        else
        {
            var update = await _inventoryRepository.Where(x => x.Id == input.Id.Value).ToOneAsync();

            if (update == null)
                throw new UserFriendlyException("产品数据不存在");

            ObjectMapper.Map(input, update);

            if (input.InventorySkus.Any())
            {
                update.InventorySkus = input.InventorySkus.Select(x =>
                {
                    var inventorySku = ObjectMapper.Map<InventorySkuInputDto, InventoryProduct>(x);

                    inventorySku.ProductNo = update.ProductNo;

                    return inventorySku;
                }).ToList();

                await _inventoryRepository.SaveManyAsync(update, nameof(update.InventorySkus));
            }

            await _inventoryRepository.UpdateAsync(update);
        }

        return true;
    }


    ///// <summary>
    /////  获取小程序端活动详情
    ///// </summary>
    ///// <returns></returns>
    //public async Task<ProductDetailOutputDto> GetClientDetailAsync(Guid id, int? scene)
    //{
    //    var model = await _productRepository
    //        .Where(x => x.Id == id)
    //        .ToOneAsync(x => new ProductDetailOutputDto
    //        {
    //            IsShowCaptain = 1,
    //            IsShowJoin = 1,
    //            IsShowShop = 0,
    //            IsShowTeam = 0,
    //            Hits = x.Hits
    //        });

    //    if (model == null)
    //        throw new UserFriendlyException("活动不存在");


    //    model.TextName = "立即抢购";
        

    //    return model;
    //}


    /// <summary>
    ///  获取产品编号
    /// </summary>
    /// <returns></returns>
    private string GetProductNo(Guid? categoryId)
    {
        var category = _sysDictionaryRepository
            .Where(x => x.Id == categoryId)
            .ToOne();

        if (category == null)
            throw new UserFriendlyException("未能找到产品分类数据");

        var inventoryProductNo = _inventoryRepository
            .Where(x => x.CategoryId == categoryId && x.ProductNo.StartsWith($"{category.Code}-"))
            .DisableGlobalFilter("SoftDelete")
            .OrderByDescending(x => x.ProductNo)
            .ToOne(x => new
            {
                x.ProductNo
            });

        if (inventoryProductNo == null || string.IsNullOrWhiteSpace(inventoryProductNo.ProductNo))
        {
            return $"{category.Code.ToUpper()}-001";
        }

        var inventoryProductNoMaxValue = new Regex(@"\d+").Match(inventoryProductNo.ProductNo).Value.ToInt();

        return $"{category.Code.ToUpper()}-{(inventoryProductNoMaxValue + 1).ToString().PadLeft(3, '0')}";
    }

    /// <summary>
    ///  逻辑删除产品
    /// </summary>
    /// <returns></returns>
    public async Task<bool> DeleteAsync([FromBody] List<Guid> ids)
    {
        var productNos = await _inventoryRepository
            .Where(x => ids.Contains(x.Id))
            .ToListAsync(x => x.ProductNo);

        var supplier = await _freeSql.Select<InventoryProduct>()
            .Where(x => productNos.Contains(x.ProductNo))
            .ToListAsync(x => x.ProductNo);
        
        var validResultList = new List<ValidationResult>();
        if (validResultList.Any())
            throw new AbpValidationException(validResultList);

        var result = await _freeSql
            .Update<Inventory>()
            .Set(a => a.IsDeleted, true)
            .Set(x => x.DeletedTime, Clock.Now)
            .Where(x => ids.Contains(x.Id))
            .ExecuteAffrowsAsync();

        _logger.LogInformation($"执行逻辑删除条数：{result} 条");

        return result > 0;
    }

    /// <summary>
    ///  表单信息
    /// </summary>
    /// <param name="id">产品编码</param>
    /// <returns></returns>
    public async Task<InventoryFormOutputDto> GetFormInfoAsync(Guid id)
    {
        if (id == Guid.Empty)
            return new InventoryFormOutputDto();

        var formInfo = await _inventoryRepository
            .Where(x => x.Id == id)
            .ToOneAsync(x => new InventoryFormOutputDto());

        if (formInfo == null)
            throw new UserFriendlyException("产品产品不存在或被管理员删除");

        var inventoryProduct = await _inventorySkuRepository
            .Where(x => x.InventoryId == formInfo.Id)
            .ToOneAsync();

        //formInfo.ProductId = inventoryProduct?.Id;
        //formInfo.Price = inventoryProduct?.Price;

        return formInfo;
    }

    /// <summary>
    ///  获得产品信息
    /// </summary>
    /// <param name="id">产品编码</param>
    /// <returns></returns>
    [DisableAuditing]
    public async Task<InventoryRawFromOutputDto> GetRawFormInfoAsync(Guid id)
    {
        if (id == Guid.Empty)
            return new InventoryRawFromOutputDto
            {
                InventorySkus = new List<InventorySkuOutputDto>
                    {
                        new()
                        {
                            Id = GuidGenerator.Create(),
                            //Price = 0,
                            Sort = 0
                        }
                    }
            };

        var formInfo = await _inventoryRepository
            .Where(x => x.Id == id)
            .ToOneAsync(x => new InventoryRawFromOutputDto());

        if (formInfo == null)
            throw new UserFriendlyException("产品不存在或被管理员删除");

        formInfo.InventorySkus = await _inventorySkuRepository
            .Where(x => x.InventoryId == id)
            .OrderByDescending(x => x.Sort)
            .ToListAsync(x => new InventorySkuOutputDto());

        return formInfo;
    }


    /// <summary>
    ///  产品列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [DisableAuditing]
    [RemoteService(IsEnabled = false)]
    public async Task<List<InventoryPagedOutputDto>> PostExportInventoryListAsync(InventoryPagedInputDto input)
    {
        var list = await _inventoryRepository
            .WhereIf(input.ProductType.HasValue, x => x.ProductType == input.ProductType)
            .WhereIf(!string.IsNullOrWhiteSpace(input.Product),
                x => x.ProductNo.Contains(input.Product) || x.ProductName.Contains(input.Product))
            .WhereIf(input.CategoryId.HasValue, x => x.CategoryId == input.CategoryId)
            .Page(input.PageIndex, input.PageSize)
            .OrderByDescending(x => x.AddTime) //按照创建时间倒序
            .Count(out _)
            .ToListAsync(x => new InventoryPagedOutputDto());

        return list;

    }

    /// <summary>
    ///  批量逻辑启用、禁用、上架、下架
    /// </summary>
    /// <returns></returns>]
    public async Task UpdateStatusAsync([FromBody] InventoryStatesInputDto input)
    {
        // 禁用
        if (input.StateType == 0)
        {
            await _freeSql.Update<Inventory>()
                .Set(x => x.Status, 0)
                .Where(x => input.Id.Contains(x.Id))
                .ExecuteAffrowsAsync();
        }
        else if (input.StateType == 1) // 启用
        {
            await _freeSql.Update<Inventory>()
                .Set(x => x.Status, 1)
                .Where(x => input.Id.Contains(x.Id))
                .ExecuteAffrowsAsync();
        }
        else if (input.StateType == 2) // 下架
        {
            await _freeSql.Update<Inventory>()
                .Set(x => x.Status, 2)
                .Where(x => input.Id.Contains(x.Id))
                .ExecuteAffrowsAsync();
        }
        else if (input.StateType == 3) // 上架
        {
            await _freeSql.Update<Inventory>()
                .Set(x => x.Status, 3)
                .Where(x => input.Id.Contains(x.Id))
                .ExecuteAffrowsAsync();
        }
    }


    /// <summary>
    ///  保存产品关联客户信息
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    /// <exception cref="AbpValidationException">验证异常</exception>
    /// <exception cref="UserFriendlyException">友好异常</exception>
    public async Task<bool> SaveInventoryWithCustomerAsync(InventoryWithCustomerSaveInputDto input)
    {
        var update = await _inventoryRepository.Where(x => x.Id == input.Id.Value).ToOneAsync();

        if (update == null)
            throw new UserFriendlyException("产品数据不存在");

        ObjectMapper.Map(input, update);

        if (input.InventoryWithCustomers.Any())
        {
            update.InventoryWithCustomers = input.InventoryWithCustomers.Select(x =>
            {
                var inventoryWithCustomer =
                    ObjectMapper.Map<InventoryWithCustomerInputDto, InventoryWithCustomer>(x);
                //计算售价
                //inventoryWithCustomer.SalePrice = inventoryWithCustomer.Discount * update.FaceAmount;
                inventoryWithCustomer.SalePrice = inventoryWithCustomer.SalePrice;
                inventoryWithCustomer.ProductNo = input.ProductNo;
                if (inventoryWithCustomer.Commission == null)
                {
                    inventoryWithCustomer.Commission = 0;
                }

                return inventoryWithCustomer;
            }).ToList();

            await _inventoryRepository.SaveManyAsync(update, nameof(update.InventoryWithCustomers));
        }

        //获得客户信息
        var customerName = "";
        var num = 1;
        foreach (var item in input.InventoryWithCustomers.OrderByDescending(x => x.SalePrice))
        {
            customerName += await _freeSql.Select<Customer>().Where(x => x.Id == item.CustomerId).ToOneAsync(x => x.Name);

            customerName += " ( " + item.SalePrice + "  )";
            if (num < input.InventoryWithCustomers.Count())
            {
                customerName += " ， ";
            }

            num++;
        }

        update.CustomerName = customerName;
        await _inventoryRepository.UpdateAsync(update);

        return true;
    }

    /// <summary>
    ///  保存产品Sku信息
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<bool> SaveInventoryShopAsync(InventoryShopSaveInputDto input)
    {
        var inventory = await _freeSql.Select<Inventory>().Where(x => x.Id == input.Id).ToOneAsync();

        if (inventory == null)
            throw new UserFriendlyException("产品数据不存在");

        ObjectMapper.Map(input, inventory);

        if (input.InventoryShops.Any())
        {
            inventory.InventoryShops = input.InventoryShops.Select(x =>
            {
                var shop = ObjectMapper.Map<InventoryShopInputDto, InventoryShop>(x);
                shop.Id = new Guid();
                shop.ProductNo = inventory.ProductNo;
                shop.InventoryId = inventory.Id;
                return shop;
            }).ToList();
            await _inventoryRepository.SaveManyAsync(inventory, nameof(inventory.InventoryShops));
        }

        await _inventoryRepository.UpdateAsync(inventory);

        return true;
    }



    /// <summary>
    ///  获得产品关联客户信息
    /// </summary>
    /// <param name="id">产品编码</param>
    /// <returns></returns>
    public async Task<InventoryWithCustomerFromOutputDto> GetInventoryWithCustomerInfoAsync(Guid id)
    {
        if (id == Guid.Empty)
            return new InventoryWithCustomerFromOutputDto
            {
                InventoryWithCustomers = new List<InventoryWithCustomerOutputDto>
                    {
                        new()
                        {
                            Id = GuidGenerator.Create(),
                            Discount = 0,
                            SalePrice = 0,
                            Commission = 0
                        }
                    }
            };

        var formInfo = await _inventoryRepository
            .Where(x => x.Id == id)
            .ToOneAsync(x => new InventoryWithCustomerFromOutputDto());

        if (formInfo == null)
            throw new UserFriendlyException("产品不存在或被管理员删除");

        formInfo.InventoryWithCustomers = await _inventoryWithCustomerRepository
            .Where(x => x.InventoryId == id)
            .OrderByDescending(x => x.AddTime)
            .ToListAsync(x => new InventoryWithCustomerOutputDto());

        if (!formInfo.InventoryWithCustomers.Any())
        {
            formInfo.InventoryWithCustomers = new List<InventoryWithCustomerOutputDto>
                {
                    new()
                    {
                        Id = GuidGenerator.Create(),
                        Discount = 0,
                        SalePrice = 0,
                        Commission = 0
                    }
                };
        }


        return formInfo;
    }

    /// <summary>
    ///  下游产品分页
    /// </summary>
    /// <returns></returns>
    [DisableAuditing]
    public async Task<PageResponseWrapper<List<InventoryWithCustomerPagedOutputDto>>> PostInventoryDownPagedAsync(
        [FromBody] InventoryPagedInputDto input)
    {
        var customerId = await _sysManagerRepository.Where(x => x.Id == _currentUser.Id)
            .ToOneAsync(x => x.CustomerId);

        var list = await _freeSql.Select<Inventory, InventoryWithCustomer>()
            .LeftJoin(x => x.t1.Id == x.t2.InventoryId)
            .WhereIf(input.ProductType.HasValue, x => x.t1.ProductType == input.ProductType)
            .WhereIf(!string.IsNullOrWhiteSpace(input.Product),
                x => x.t1.ProductNo.Contains(input.Product) || x.t1.ProductName.Contains(input.Product))
            .WhereIf(customerId != null, x => x.t2.CustomerId == customerId)
            .Page(input.PageIndex, input.PageSize)
            .OrderByDescending(x => x.t1.AddTime) //按照创建时间倒序
            .Count(out var pageTotalCount)
            .ToListAsync(x => new InventoryWithCustomerPagedOutputDto
            {
                Id = x.t1.Id,
                //AddUserName = x.t2.Name
            });

        var page = new PageResponseWrapper<List<InventoryWithCustomerPagedOutputDto>>
        {
            Total = pageTotalCount,
            Items = list
        };

        return page;
    }



    /// <summary>
    ///  获得当前客户所配置的产品列表
    /// </summary>
    /// <param name="name">管理员名字</param>
    /// <returns></returns>
    public async Task<List<InventoryOptionOutputDto>> GetOptionListByNameAsync(string name)
    {
        var customerId = await _sysManagerRepository.Where(x => x.Id == _currentUser.Id)
            .ToOneAsync(x => x.CustomerId);

        var list = await _freeSql.Select<Inventory, InventoryWithCustomer>()
            .LeftJoin(x => x.t1.Id == x.t2.InventoryId)
            .WhereIf(!string.IsNullOrWhiteSpace(name),
                x => x.t1.ProductNo.Contains(name) || x.t1.ProductName.Contains(name))
            .WhereIf(customerId != null, x => x.t2.CustomerId == customerId)
            .ToListAsync(x => new InventoryOptionOutputDto
            {
                Label = x.t1.ProductName,
                Value = x.t1.Id,
                ProductNo = x.t1.ProductNo,
                SalePrice = x.t2.SalePrice
            });

        return list;
    }


    /// <summary>
    ///  获得产品店铺配置信息
    /// </summary>
    /// <param name="id">产品编码</param>
    /// <returns></returns>
    public async Task<InventoryShopFromOutputDto> GetInventoryShopInfoAsync(Guid id)
    {
        if (id == Guid.Empty)
            return new InventoryShopFromOutputDto
            {
                InventoryShops = new List<InventoryShopOutputDto>
                {
                    new()
                    {
                        Id = GuidGenerator.Create()
                    }
                }
            };

        var formInfo = await _inventoryRepository
            .Where(x => x.Id == id)
            .ToOneAsync(x => new InventoryShopFromOutputDto());

        if (formInfo == null)
            throw new UserFriendlyException("产品不存在或被管理员删除");

        formInfo.InventoryShops = await _freeSql.Select<InventoryShop>()
            .Where(x => x.InventoryId == id)
            .OrderByDescending(x => x.AddTime)
            .ToListAsync(x => new InventoryShopOutputDto());

        if (!formInfo.InventoryShops.Any())
        {
            formInfo.InventoryShops = new List<InventoryShopOutputDto>
            {
                new()
                {
                    Id = GuidGenerator.Create()
                }
            };
        }


        return formInfo;
    }



    /// <summary>
    ///  获取管理后台产品选项列表
    /// </summary>
    /// <param name="name">产品名字</param>
    /// <param name="type">产品类别：1=存量业务；2=其余业务</param>
    /// <returns></returns>
    public async Task<List<OptionOutputIdDto>> GetOptionListAsync(string name, int type)
    {
        var list = await _freeSql.Select<Inventory>()
            .WhereIf(!string.IsNullOrWhiteSpace(name), x => x.ProductName.Contains(name) || x.ProductNo.Contains(name))
            .Where(x => x.Status == 3)
            .OrderByDescending(x => x.Sort)
            .OrderByDescending(x => x.AddTime)
            .ToListAsync(x => new OptionOutputIdDto
            {
                Label = $"{x.ProductNo}-[{x.ProductName}]",
                Value = x.Id,
                Data = new
                {
                    x.FaceAmount,
                    x.FaceRemark
                }
            });

        return list;
    }

    
    /// <summary>
    ///  本地星商品分页
    /// </summary>
    /// <returns></returns>
    [DisableAuditing]
    public async Task<PageResponseWrapper<List<CustomerInventoryPagedOutputDto>>> PostLocalStarPagedAsync([FromBody] InventoryPagedInputDto input)
    {

        var list = await _freeSql.Select<Inventory, SysManager, InventoryWithCustomer, Customer>()
            .LeftJoin(x => x.t1.AddUserId == x.t2.Id)
            .LeftJoin(x => x.t1.Id == x.t3.InventoryId)
            .LeftJoin(x => x.t3.CustomerId == x.t4.Id)
            .WhereIf(input.ProductType.HasValue, x => x.t1.ProductType == input.ProductType)
            .WhereIf(!string.IsNullOrWhiteSpace(input.Product), x => x.t1.ProductNo.Contains(input.Product) || x.t1.ProductName.Contains(input.Product))
            .Where(x => x.t1.Status == 3 && x.t4.Code == 38737)
            .Page(input.PageIndex, input.PageSize)
            .OrderByDescending(x => x.t1.Sort)
            .OrderByDescending(x => x.t1.AddTime) //按照创建时间倒序
            .Count(out var pageTotalCount)
            .ToListAsync(x => new CustomerInventoryPagedOutputDto
            {
                Id = x.t1.Id,
                AddUserName = x.t2.Name,
                CustomerName = x.t4.Name,
                Discount = x.t3.Discount,
                SalePrice = x.t3.SalePrice,
                CustomerCode = x.t4.Code.ToString()

            });

        var page = new PageResponseWrapper<List<CustomerInventoryPagedOutputDto>>
        {
            Total = pageTotalCount,
            Items = list
        };

        return page;
    }


}
